<!-- build time:Wed Apr 17 2019 20:00:12 GMT+0800 (GMT+08:00) --><!DOCTYPE html><html lang="zh"><head><meta name="generator" content="Hexo 3.8.0"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui"><meta name="renderer" content="webkit"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="format-detection" content="telephone=no,email=no,adress=no"><meta name="theme-color" content="#000000"><meta http-equiv="window-target" content="_top"><title>扫地僧的博客</title><meta property="og:type" content="website"><meta property="og:title" content="Hello World"><meta property="og:url" content="http://lizx999.gitee.io/xingges_blog/index.html"><meta property="og:site_name" content="Hello World"><meta property="og:locale" content="zh-CN"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="Hello World"><link rel="canonical" href="http://lizx999.gitee.io/xingges_blog/index.html"><link rel="alternate" href="/atom.xml" title="Hello World" type="application/atom+xml"><link rel="icon" href="/favicon.png" type="image/x-icon"><link rel="stylesheet" href="/xingges_blog/css/style.css"></head><body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="slimContent"><div class="navbar-header"><div class="profile-block text-center"><a id="avatar" href="https://gitee.com/lizx999" target="_blank"><img class="img-circle img-rotate" src="/xingges_blog/images/saodizeng.jpg" width="200" height="200"></a><h2 id="name" class="hidden-xs hidden-sm">扫地僧</h2><h3 id="title" class="hidden-xs hidden-sm hidden-md">一个半路出家的IT民工</h3><small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> 北京, 中国</small></div><div class="search" id="search-form-wrap"><form class="search-form sidebar-form"><div class="input-group"><input type="text" class="search-form-input form-control" placeholder="搜索"> <span class="input-group-btn"><button type="submit" class="search-form-submit btn btn-flat" onclick="return!1"><i class="icon icon-search"></i></button></span></div></form><div class="ins-search"><div class="ins-search-mask"></div><div class="ins-search-container"><div class="ins-input-wrapper"><input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech> <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="ins-section-wrapper"><div class="ins-section-container"></div></div></div></div></div><button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false"><span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span></button></div><nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation"><ul class="nav navbar-nav main-nav menu-highlight"><li class="menu-item menu-item-home"><a href="/xingges_blog/."><i class="icon icon-home-fill"></i> <span class="menu-title">首页</span></a></li><li class="menu-item menu-item-archives"><a href="/xingges_blog/archives"><i class="icon icon-archives-fill"></i> <span class="menu-title">归档</span></a></li><li class="menu-item menu-item-categories"><a href="/xingges_blog/categories"><i class="icon icon-folder"></i> <span class="menu-title">分类</span></a></li><li class="menu-item menu-item-tags"><a href="/xingges_blog/tags"><i class="icon icon-tags"></i> <span class="menu-title">标签</span></a></li><li class="menu-item menu-item-repository"><a href="/xingges_blog/repository"><i class="icon icon-project"></i> <span class="menu-title">项目</span></a></li><li class="menu-item menu-item-about"><a href="/xingges_blog/about"><i class="icon icon-cup-fill"></i> <span class="menu-title">关于</span></a></li></ul><ul class="social-links"><li><a href="https://gitee.com/lizx999" target="_blank" title="Gitee" data-toggle="tooltip" data-placement="top"><i class="icon icon-gitee"></i></a></li><li><a href="/xingges_blog/atom.xml" target="_blank" title="Rss" data-toggle="tooltip" data-placement="top"><i class="icon icon-rss"></i></a></li></ul></nav></div></header><aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar"><div class="slimContent"><div class="widget"><h3 class="widget-title">公告</h3><div class="widget-body"><div id="board"><div class="content"><p>扫地僧第一次写博客，心情激动无限</p></div></div></div></div><div class="widget"><h3 class="widget-title">标签</h3><div class="widget-body"><ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/xingges_blog/tags/python/">python</a><span class="tag-list-count">1</span></li></ul></div></div><div class="widget"><h3 class="widget-title">标签云</h3><div class="widget-body tagcloud"><a href="/xingges_blog/tags/python/" style="font-size:13px">python</a></div></div><div class="widget"><h3 class="widget-title">归档</h3><div class="widget-body"><ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/xingges_blog/archives/2019/04/">四月 2019</a><span class="archive-list-count">1</span></li></ul></div></div><div class="widget"><h3 class="widget-title">最新文章</h3><div class="widget-body"><ul class="recent-post-list list-unstyled no-thumbnail"><li><div class="item-inner"><p class="item-category"></p><p class="item-title"><a href="/xingges_blog/2019/04/16/Django笔记/" class="title">Django</a></p><p class="item-date"><time datetime="2019-04-16T11:22:00.000Z" itemprop="datePublished">2019-04-16</time></p></div></li></ul></div></div></div></aside><main class="main" role="main"><div class="content"><article id="post-Django笔记" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting"><div class="article-header"><h1 itemprop="name"><a class="article-title" href="/xingges_blog/2019/04/16/Django笔记/">Django</a></h1><div class="article-meta"><span class="article-date"><i class="icon icon-calendar-check"></i> <a href="/xingges_blog/2019/04/16/Django笔记/" class="article-date"><time datetime="2019-04-16T11:22:00.000Z" itemprop="datePublished">2019-04-16</time></a></span> <span class="article-tag"><i class="icon icon-tags"></i> <a class="article-tag-link" href="/xingges_blog/tags/python/">python</a></span> <span class="article-read hidden-xs"><i class="icon icon-eye-fill" aria-hidden="true"></i> <span id="busuanzi_container_page_pv"><span id="busuanzi_value_page_pv">0</span></span></span> <span class="post-comment"><i class="icon icon-comment"></i> <a href="/xingges_blog/2019/04/16/Django笔记/#comments" class="article-comment-link">评论</a></span> <span class="post-wordcount hidden-xs" itemprop="wordCount">字数统计: 10.2k(字)</span> <span class="post-readcount hidden-xs" itemprop="timeRequired">阅读时长: 47(分)</span></div></div><div class="article-entry marked-body" itemprop="articleBody"><h2 id="django学习"><a class="markdownIt-Anchor" href="#django学习"></a> Django学习</h2><h4 id="一-django简介"><a class="markdownIt-Anchor" href="#一-django简介"></a> 一、Django简介</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">urls.py:网址入口，关联到对应的views.py中的一个函数（或者generic类），访问网址就对应一个函数。</span><br><span class="line">views.py:处理用户发出的请求，从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容，比如登陆后的          用户名，用户请求的数据，输出到网页</span><br><span class="line">models.py:与数据库操作相关，存入或读取数据时用到这个，当然用不到数据库的时候 你可以不使用.</span><br><span class="line">forms.py:表单，用户在浏览器上输入数据提交，对数据的验证工作以及输入框的生成等工作，当然你也可以不使用。</span><br><span class="line">templates:文件夹,views.py 中的函数渲染templates中的Html模板，得到动态内容的网页，当然可以用缓存来提高           速度。</span><br><span class="line">admin.py:后台，可以用很少量的代码就拥有一个强大的后台。</span><br><span class="line">settings.py:Django 的设置，配置文件，比如 DEBUG 的开关，静态文件的位置等。</span><br></pre></td></tr></table></figure><h4 id="二-django基本命令"><a class="markdownIt-Anchor" href="#二-django基本命令"></a> 二、Django基本命令</h4><p>1、 新建一个 django project</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">django-admin.py startproject project-name  </span><br><span class="line">注意：</span><br><span class="line">1、在windows中如果报错，使用django-admin试试</span><br><span class="line">2、一个 project 为一个项目，project-name为项目名称，要符合Python 的变量命名规则（以下划线或字母开头）</span><br></pre></td></tr></table></figure><p>2、新建app：一般一个项目有多个app，一个通用app也可以在多个项目中使用。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py startapp app-name  或 django-admin.py startapp app-name</span><br></pre></td></tr></table></figure><p>3、同步数据库：当你在models.py中新增了类时，运行它就可以自动在数据库中创建表了，不用手动创建。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1.7以下：</span><br><span class="line">python manage.py syncdb</span><br><span class="line">1.7以上：</span><br><span class="line">python manage.py makemigrations</span><br><span class="line">python manage.py migrate</span><br></pre></td></tr></table></figure><p>4、清空数据库，会清除数据，只留空表</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python manage.py flush</span><br><span class="line">#选择yes会把数据清掉，只留空表。</span><br></pre></td></tr></table></figure><p>5、启动测试服务</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py runserver 0.0.0.0:8000</span><br></pre></td></tr></table></figure><p>6、创建超级管理员和修改超级管理员密码</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python manage.py createsuperuser    #创建</span><br><span class="line">python manage.py changepassword username  #修改密码</span><br></pre></td></tr></table></figure><p>7、导出数据 导入数据</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python manage.py dumpdata appname &gt; appname.json</span><br><span class="line">python manage.py loaddata appname.json</span><br></pre></td></tr></table></figure><p>8、django shell</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py shell</span><br></pre></td></tr></table></figure><p>9、数据库shell</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py dbshell</span><br></pre></td></tr></table></figure><h4 id="三-视图views"><a class="markdownIt-Anchor" href="#三-视图views"></a> 三、视图(views)</h4><p>1、定义app的配置，将app添加到setting.py中</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">INSTALLED_APPS = (</span><br><span class="line">    <span class="string">'django.contrib.admin'</span>,</span><br><span class="line">    <span class="string">'django.contrib.auth'</span>,</span><br><span class="line">    <span class="string">'django.contrib.contenttypes'</span>,</span><br><span class="line">    <span class="string">'django.contrib.sessions'</span>,</span><br><span class="line">    <span class="string">'django.contrib.messages'</span>,</span><br><span class="line">    <span class="string">'django.contrib.staticfiles'</span>,</span><br><span class="line"> </span><br><span class="line">    <span class="string">'app名字'</span>,</span><br><span class="line">)</span><br><span class="line">解释：</span><br><span class="line">新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件)</span><br></pre></td></tr></table></figure><p>2、定义视图函数（访问页面时的内容),在views.py中</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#coding:utf-8</span></span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">u"欢迎！"</span>)</span><br><span class="line">解释：</span><br><span class="line">HttpResponse，它是用来向网页返回内容的，就像Python中的 <span class="keyword">print</span> 一样，只不过 HttpResponse 是把内容显示到网页上。</span><br><span class="line">代码解释：</span><br><span class="line">定义了一个index()函数，第一个参数必须是 request，与网页发来的请求有关，request 变量里面包含get或post的内容，用户浏览器，系统等信息在里面，函数返回了一个 HttpResponse 对象，可以经过一些处理，最终显示几个字到网页上。</span><br></pre></td></tr></table></figure><p>3、定义视图函数相关的URL(网址) （即规定 访问什么网址对应什么内容），即urls.py中的配置</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> url</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> app名字 <span class="keyword">import</span> views <span class="keyword">as</span> app别名  <span class="comment"># new</span></span><br><span class="line"> </span><br><span class="line">urlpatterns = [</span><br><span class="line">    url(<span class="string">r'^$'</span>, app别名.视图函数的名字),  <span class="comment"># new</span></span><br><span class="line">    url(<span class="string">r'^admin/'</span>, admin.site.urls),</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>4、采用 **/add/?a=4&amp;b=5 **这样GET方法进行</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">views配置如下：</span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render</span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span><span class="params">(request)</span>:</span></span><br><span class="line">    a = request.GET[<span class="string">'a'</span>] </span><br><span class="line">    b = request.GET[<span class="string">'b'</span>]</span><br><span class="line">    c = int(a)+int(b)</span><br><span class="line">    <span class="keyword">return</span> HttpResponse(str(c))</span><br><span class="line"><span class="comment">#request.GET 类似于一个字典，更好的办法是用 request.GET.get('a', 0) 当没有传递 a 的时候默认 a 为 0</span></span><br><span class="line">urls.py配置如下：</span><br><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> url</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> calc <span class="keyword">import</span> views <span class="keyword">as</span> calc_views </span><br><span class="line">urlpatterns = [</span><br><span class="line">    url(<span class="string">r'^add/$'</span>, calc_views.add, name=<span class="string">'add'</span>),  <span class="comment"># 注意修改了这一行</span></span><br><span class="line">    url(<span class="string">r'^admin/'</span>, admin.site.urls),</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>5、采用 /add/3/4/ 这样的网址的方式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">views配置如下：</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add2</span><span class="params">(request, a, b)</span>:</span></span><br><span class="line">    c = int(a) + int(b)</span><br><span class="line">    <span class="keyword">return</span> HttpResponse(str(c)</span><br><span class="line">urls配置如下：</span><br><span class="line">url(<span class="string">r'^add/(\d+)/(\d+)/$'</span>, calc_views.add2, name=<span class="string">'add2'</span>),</span><br><span class="line">解释：</span><br><span class="line">正则表达式中 \d 代表一个数字，+ 代表一个或多个前面的字符，写在一起 \d+ 就是一个或多个数字，用括号括起来的意思是保存为一个子组（更多知识请参见 Python 正则表达式），每一个子组将作为一个参数，被 views.py 中的对应视图函数接收。</span><br></pre></td></tr></table></figure><h4 id="四-url-name详解"><a class="markdownIt-Anchor" href="#四-url-name详解"></a> 四、URL NAME详解</h4><p>1、先看段代码，通过代码进行解释</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> url</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> calc <span class="keyword">import</span> views <span class="keyword">as</span> calc_views</span><br><span class="line"> </span><br><span class="line">urlpatterns = [</span><br><span class="line">    url(<span class="string">r'^add/$'</span>, calc_views.add, name=<span class="string">'add'</span>),</span><br><span class="line">    url(<span class="string">r'^add/(\d+)/(\d+)/$'</span>, calc_views.add2, name=<span class="string">'add2'</span>),</span><br><span class="line">    url(<span class="string">r'^admin/'</span>, admin.site.urls),</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>解释如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name:可以用于在 templates, models, views ……中得到对应的网址，相当于“给网址取了个名字”，只要这个名字不变，网址变      了也能通过名字获取到。这个参数设定好后不要轻易改。</span><br></pre></td></tr></table></figure><p>2、在ptyhon shell中测试url的方式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">python manage.py shell</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> django.core.urlresolvers <span class="keyword">import</span> reverse  <span class="comment"># django 1.4.x - django 1.10.x</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> django.urls <span class="keyword">import</span> reverse  <span class="comment"># django 1.10.x 新的，更加规范了</span></span><br><span class="line"> </span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>reverse(<span class="string">'add2'</span>, args=(<span class="number">4</span>,<span class="number">5</span>))</span><br><span class="line"><span class="string">u'/add/4/5/'</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>reverse(<span class="string">'add2'</span>, args=(<span class="number">444</span>,<span class="number">555</span>))</span><br><span class="line"><span class="string">u'/add/444/555/'</span></span><br></pre></td></tr></table></figure><p>解释如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reverse 接收 url 中的 name 作为第一个参数,我们在代码中就可以通过 reverse() 来获取对应的网址（这个网址可以用来跳转，也可以用来计算相关页面的地址），只要对应的 url 的name不改，就不用改代码中的网址。</span><br></pre></td></tr></table></figure><p>在网页模板中也是一样，可以很方便的使用。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">不带参数的：</span><br><span class="line">&#123;% url 'name' %&#125;</span><br><span class="line">带参数的：参数可以是变量名</span><br><span class="line">&#123;% url 'name' 参数 %&#125;</span><br><span class="line"> </span><br><span class="line">例如：</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"&#123;% url 'add2' 4 5 %&#125;"</span>&gt;</span>link<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">渲染成最终的页面是:</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/add/4/5/"</span>&gt;</span>link<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">就可以通过 &#123;% url 'add2' 4 5 %&#125; 获取到对应的网址 /add/4/5/</span><br></pre></td></tr></table></figure><p>urls.py中修改注意事项</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1、当 urls.py 进行更改，前提是不改 name（这个参数设定好后不要轻易改），获取的网址也会动态地跟着变,</span><br><span class="line">2、用在 views.py 或 models.py 等地方的 reverse函数，同样会根据 name 对应的url获取到新的网址。</span><br><span class="line">3、想要改网址的时候，修改 urls.py 中的正则表达式部分（url 参数第一部分），name 不变的前提下，其它地方都不需要修改。</span><br></pre></td></tr></table></figure><p>3、urls的跳转</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">用户收藏夹中收藏的URL是旧的，如何让以前的 自动跳转到现在新的网址呢？</span><br><span class="line"><span class="number">1</span>、在views中的跳转函数如下：</span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponseRedirect</span><br><span class="line"><span class="keyword">from</span> django.core.urlresolvers <span class="keyword">import</span> reverse  <span class="comment"># django 1.4.x - django 1.10.x</span></span><br><span class="line"><span class="comment">#  from django.urls import reverse  # new in django 1.10.x</span></span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">old_add2_redirect</span><span class="params">(request, a, b)</span>:</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponseRedirect(reverse(<span class="string">'add2'</span>, args=(a, b)))</span><br><span class="line"><span class="number">2</span>、在urls.py中：</span><br><span class="line">url(<span class="string">r'^add/(\d+)/(\d+)/$'</span>, calc_views.old_add2_redirect),</span><br><span class="line">url(<span class="string">r'^new_add/(\d+)/(\d+)/$'</span>, calc_views.add2, name=<span class="string">'add2'</span>),</span><br></pre></td></tr></table></figure><h4 id="五-django模版"><a class="markdownIt-Anchor" href="#五-django模版"></a> 五、Django模版</h4><p>默认配置下，Django 的模板系统会自动找到app下面的templates文件夹中的模板文件。网站模板的设计，一般的，我们做网站有一些通用的部分，比如 导航，底部，访问统计代码等等<strong>nav.html, bottom.html, tongji.html</strong></p><p>基本模版</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE html&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>&#123;% block title %&#125;默认标题&#123;% endblock %&#125; - 自强学堂<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"> </span><br><span class="line">&#123;% include 'nav.html' %&#125;</span><br><span class="line"> </span><br><span class="line">&#123;% block content %&#125;</span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">      这里是默认内容，所有继承自这个模板的，如果不覆盖就显示这里的默认内容。</span><br><span class="line">  	<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">&#123;% endblock %&#125;</span><br><span class="line"> </span><br><span class="line">&#123;% include 'bottom.html' %&#125; </span><br><span class="line">&#123;% include 'tongji.html' %&#125;</span><br><span class="line"> </span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>include</strong> 是包含其它文件的内容，就是把一些网页共用的部分拿出来，重复利用，改动的时候也方便一些，还可以把广告代码放在一个单独的html中，改动也方便一些，在用到的地方include进去。其它的页面继承自 <strong>base.html</strong> 就好了，继承后的模板也可以在 block 块中 include 其它的模板文件。</p><p>继承或者说扩展(extends)原来的 **base.html，**可以简单这样写，重写部分代码（默认值的那一部分不用改）</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&#123;% extends 'base.html' %&#125;</span><br><span class="line"> </span><br><span class="line">&#123;% block title %&#125;欢迎光临首页&#123;% endblock %&#125;</span><br><span class="line"> </span><br><span class="line">&#123;% block content %&#125;</span><br><span class="line">&#123;% include 'ad.html' %&#125;</span><br><span class="line">这里是首页，欢迎光临</span><br><span class="line">&#123;% endblock %&#125;</span><br></pre></td></tr></table></figure><p>注意：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">模板一般放在app下的templates中，Django会自动去这个文件夹中找。但 假如我们每个app的templates中都有一个 index.html，当我们在views.py中使用的时候，直接写一个 render(request, &apos;index.html&apos;)，Django 能不能找到当前 app 的 templates 文件夹中的 index.html 文件夹呢?（答案是不一定能，有可能找错）</span><br></pre></td></tr></table></figure><p>django的查找机制</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"> Django 查找模板的过程是在每个 app 的 templates 文件夹中找（而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找）。各个 app 的 templates 形成一个文件夹列表，Django 遍历这个列表，一个个文件夹进行查找，当在某一个文件夹找到的时候就停止，所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found （过程类似于Python找包）。这样设计有利当然也有弊，有利是的地方是一个app可以用另一个app的模板文件，弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹，这样就好了。</span><br><span class="line">这就需要把每个app中的 templates 文件夹中再建一个 app 的名称，仅和该app相关的模板放在 app/templates/app/ 目录下面，使用的时候，模板就是 &quot;tutorial/index.html&quot; 和 &quot;tryit/index.html&quot; 这样有app作为名称的一部分，就不会混淆。例：</span><br><span class="line">zqxt</span><br><span class="line">├── tutorial</span><br><span class="line">│   ├── __init__.py</span><br><span class="line">│   ├── admin.py</span><br><span class="line">│   ├── models.py</span><br><span class="line">│   ├── templates</span><br><span class="line">│   │   └── tutorial</span><br><span class="line">│   │       ├── index.html</span><br><span class="line">│   │       └── search.html</span><br><span class="line">│   ├── tests.py</span><br><span class="line">│   └── views.py</span><br><span class="line">├── tryit</span><br><span class="line">│   ├── __init__.py</span><br><span class="line">│   ├── admin.py</span><br><span class="line">│   ├── models.py</span><br><span class="line">│   ├── templates</span><br><span class="line">│   │   └── tryit</span><br><span class="line">│   │       ├── index.html</span><br><span class="line">│   │       └── poll.html</span><br><span class="line">│   ├── tests.py</span><br><span class="line">│   └── views.py</span><br><span class="line">├── manage.py</span><br><span class="line">└── zqxt</span><br><span class="line">    ├── __init__.py</span><br><span class="line">    ├── settings.py</span><br><span class="line">    ├── urls.py</span><br><span class="line">    └── wsgi.py</span><br></pre></td></tr></table></figure><h4 id="六模版进阶"><a class="markdownIt-Anchor" href="#六模版进阶"></a> 六模版进阶</h4><p>1、上下文管理器</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">render(request,<span class="string">'模版名'</span>，&#123;‘string’: string&#125;)</span><br></pre></td></tr></table></figure><p>2、传递一个views里的字符串变量，并显示在模版中</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">视图如下：</span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">home</span><span class="params">(request)</span>:</span></span><br><span class="line">    string = <span class="string">u"我在自强学堂学习Django，用它来建网站"</span></span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'home.html'</span>, &#123;<span class="string">'string'</span>: string&#125;)</span><br><span class="line">模版中如下：</span><br><span class="line">&#123;&#123; string &#125;&#125;</span><br></pre></td></tr></table></figure><p>3、传递一个views中的列表，并在模版循环显示</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">视图中：</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">home</span><span class="params">(request)</span>:</span></span><br><span class="line">    TutorialList = [<span class="string">"HTML"</span>, <span class="string">"CSS"</span>, <span class="string">"jQuery"</span>, <span class="string">"Python"</span>, <span class="string">"Django"</span>]</span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'home.html'</span>, &#123;<span class="string">'TutorialList'</span>: TutorialList&#125;)</span><br><span class="line">模版中：</span><br><span class="line">教程列表：</span><br><span class="line">&#123;% <span class="keyword">for</span> i <span class="keyword">in</span> TutorialList %&#125;</span><br><span class="line">&#123;&#123; i &#125;&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure><p>4、传递一个字典，并在模版显示</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">视图中：</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">home</span><span class="params">(request)</span>:</span></span><br><span class="line">    info_dict = &#123;<span class="string">'site'</span>: <span class="string">u'自强学堂'</span>, <span class="string">'content'</span>: <span class="string">u'各种IT技术教程'</span>&#125;</span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'home.html'</span>, &#123;<span class="string">'info_dict'</span>: info_dict&#125;)</span><br><span class="line">模版中：</span><br><span class="line">站点：&#123;&#123; info_dict.site &#125;&#125; 内容：&#123;&#123; info_dict.content &#125;&#125;</span><br><span class="line">遍历字典：</span><br><span class="line">&#123;% <span class="keyword">for</span> key, value <span class="keyword">in</span> info_dict.items %&#125;</span><br><span class="line">    &#123;&#123; key &#125;&#125;: &#123;&#123; value &#125;&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br><span class="line">注意：</span><br><span class="line">模板中取字典的键是用点info_dict.site，而不是Python中的 info_dict[<span class="string">'site'</span>]。</span><br></pre></td></tr></table></figure><p>5、在模版中for循环和判断</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">以逗号连接元素</span><br><span class="line">&#123;% for item in List %&#125;</span><br><span class="line">    &#123;&#123; item &#125;&#125;, </span><br><span class="line">&#123;% endfor %&#125;</span><br><span class="line">for循环中加判断</span><br><span class="line">&#123;% for item in List %&#125;</span><br><span class="line">    &#123;&#123; item &#125;&#125;&#123;% if not forloop.last %&#125;,&#123;% endif %&#125; </span><br><span class="line">&#123;% endfor %&#125;</span><br><span class="line">当列表中可能为空值时用 for  empty</span><br><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">&#123;% for athlete in athlete_list %&#125;</span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span>&gt;</span>&#123;&#123; athlete.name &#125;&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">&#123;% empty %&#125;</span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span>&gt;</span>抱歉，列表为空<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">&#123;% endfor %&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br></pre></td></tr></table></figure><p>if判断的变量及定义</p><table><thead><tr><th>变量</th><th>定义</th></tr></thead><tbody><tr><td>forloop.counter</td><td>索引从 1 开始算</td></tr><tr><td>forloop.counter0</td><td>索引从 0 开始算</td></tr><tr><td>forloop.revcounter</td><td>索引从最大长度到 1</td></tr><tr><td>forloop.revcounter0</td><td>索引从最大长度到 0</td></tr><tr><td>forloop.first</td><td>当遍历的元素为第一项时为真</td></tr><tr><td>forloop.last</td><td>当遍历的元素为最后一项时为真</td></tr><tr><td>forloop.parentloop</td><td>用在嵌套的 for 循环中， 获取上一层 for 循环的 forloop</td></tr></tbody></table><p>6、模板上得到视图对应的网址</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"># views.py</span><br><span class="line">def add(request, a, b):</span><br><span class="line">    c = int(a) + int(b)</span><br><span class="line">    return HttpResponse(str(c)) </span><br><span class="line"># urls.py</span><br><span class="line">urlpatterns = patterns(&apos;&apos;,</span><br><span class="line">    url(r&apos;^add/(\d+)/(\d+)/$&apos;, &apos;app.views.add&apos;, name=&apos;add&apos;),</span><br><span class="line">)</span><br><span class="line"># template html</span><br><span class="line">&#123;% url &apos;add&apos; 4 5 %&#125;</span><br></pre></td></tr></table></figure><p>注意：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">如果是 Django 1.4 的话，需要在模板开头加上 &#123;% load url from future %&#125; (如果有 extends 的话，加在 extends 下面）</span><br></pre></td></tr></table></figure><p>7、使用 as 语句将内容取别名（相当于定义一个变量），多次使用（但视图名称到网址转换只进行了一次）</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% url 'some-url-name' arg arg2 as the_url %&#125;</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"&#123;&#123; the_url &#125;&#125;"</span>&gt;</span>链接到：&#123;&#123; the_url &#125;&#125;<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br></pre></td></tr></table></figure><p>8、模板中的逻辑操作：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">1、 ==, !=, &gt;=, &lt;=, &gt;, &lt; 这些比较都可以在模板中使用</span><br><span class="line">    &#123;% if var &gt;= 90 %&#125;</span><br><span class="line">    成绩优秀，自强学堂你没少去吧！学得不错</span><br><span class="line">    &#123;% elif var &gt;= 80 %&#125;</span><br><span class="line">    成绩良好</span><br><span class="line">    &#123;% elif var &gt;= 70 %&#125;</span><br><span class="line">    成绩一般</span><br><span class="line">    &#123;% elif var &gt;= 60 %&#125;</span><br><span class="line">    需要努力</span><br><span class="line">    &#123;% else %&#125;</span><br><span class="line">    不及格啊，大哥！多去自强学堂学习啊！</span><br><span class="line">    &#123;% endif %&#125;</span><br><span class="line">2、and, or, not, in, not in 也可以在模板中使用</span><br><span class="line">    &#123;% if num &lt;= 100 and num &gt;= 0 %&#125;</span><br><span class="line">    num在0到100之间</span><br><span class="line">    &#123;% else %&#125;</span><br><span class="line">    数值不在范围之内！</span><br><span class="line">	&#123;% endif %&#125;</span><br><span class="line">3、in</span><br><span class="line">	&#123;% if &apos;ziqiangxuetang&apos; in List %&#125;</span><br><span class="line">		自强学堂在名单中</span><br><span class="line">	&#123;% endif %&#125;</span><br></pre></td></tr></table></figure><h4 id="七-模型models"><a class="markdownIt-Anchor" href="#七-模型models"></a> 七、模型models</h4><p>新建对象的方法</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">1、Person.objects.create(name=name,age=age)</span><br><span class="line">2、p = Person(name=&quot;WZ&quot;, age=23)</span><br><span class="line">   p.save()</span><br><span class="line">3、p = Person(name=&quot;TWZ&quot;)</span><br><span class="line">   p.age = 23</span><br><span class="line">   p.save()</span><br><span class="line">4、Person.objects.get_or_create(name=&quot;WZT&quot;, age=23)</span><br><span class="line">第四种方法是防止重复很好的方法，但是速度要相对慢些，返回一个元组，第一个为Person对象，第二个为True或False, 新建时返回的是True, 已经存在时返回False.</span><br></pre></td></tr></table></figure><p>获取对象的方法：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Person.objects.all()</span><br><span class="line">Person.objects.all()[:10]     切片操作，获取10个人，不支持负索引，切片可以节约内存</span><br><span class="line">Person.objects.get(name=name) get是用来获取一个对象的，如果需要获取满足条件的一些人，就要用到filter</span><br><span class="line">Person.objects.filter(name=&quot;abc&quot;) #等于Person.objects.filter(name__exact=&quot;abc&quot;) 名称严格等于 &quot;abc&quot; 的人</span><br><span class="line">Person.objects.filter(name__iexact=&quot;abc&quot;)#名称为 abc 但是不区分大小写，可以找到 ABC, Abc, aBC，这些都符合条件</span><br><span class="line">Person.objects.filter(name__contains=&quot;abc&quot;) # 名称中包含 &quot;abc&quot;的人</span><br><span class="line">Person.objects.filter(name__icontains=&quot;abc&quot;) #名称中包含 &quot;abc&quot;，且abc不区分大小写</span><br><span class="line">Person.objects.filter(name__regex=&quot;^abc&quot;) # 正则表达式查询</span><br><span class="line">Person.objects.filter(name__iregex=&quot;^abc&quot;)# 正则表达式不区分大小写,filter是找出满足条件的，当然也有排除符合某条件的</span><br><span class="line">Person.objects.exclude(name__contains=&quot;WZ&quot;) # 排除包含 WZ 的Person对象</span><br><span class="line">Person.objects.filter(name__contains=&quot;abc&quot;).exclude(age=23) # 找出名称含有abc, 但是排除年龄是23岁的</span><br></pre></td></tr></table></figure><h4 id="八-django-自定义field"><a class="markdownIt-Anchor" href="#八-django-自定义field"></a> 八、Django 自定义Field</h4><p>1、减少文本的长度，保存数据的时候压缩，读取的时候解压缩，如果发现压缩后更长，就用原文本直接存储</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.7</span>版本以下</span><br><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CompressedTextField</span><span class="params">(models.TextField)</span>:</span></span><br><span class="line">    <span class="string">"""    model Fields for storing text in a compressed format (bz2 by default)    """</span></span><br><span class="line">    __metaclass__ = models.SubfieldBase</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">to_python</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            <span class="keyword">return</span> value.decode(<span class="string">'base64'</span>).decode(<span class="string">'bz2'</span>).decode(<span class="string">'utf-8'</span>)</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_prep_value</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            value.decode(<span class="string">'base64'</span>)</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                tmp = value.encode(<span class="string">'utf-8'</span>).encode(<span class="string">'bz2'</span>).encode(<span class="string">'base64'</span>)</span><br><span class="line">            <span class="keyword">except</span> Exception:</span><br><span class="line">                <span class="keyword">return</span> value</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">if</span> len(tmp) &gt; len(value):</span><br><span class="line">                    <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">                <span class="keyword">return</span> tmp</span><br><span class="line">to_python 函数用于转化数据库中的字符到 Python的变量， get_prep_value 用于将Python变量处理后(此处为压缩）保存到数据库，使用和Django自带的 Field 一样。</span><br><span class="line"> </span><br><span class="line">                                                                  <span class="number">1.8</span>版本以上：</span><br><span class="line"> <span class="comment">#coding:utf-8</span></span><br><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CompressedTextField</span><span class="params">(models.TextField)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    model Fields for storing text in a compressed format (bz2 by default)</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">from_db_value</span><span class="params">(self, value, expression, connection, context)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            <span class="keyword">return</span> value.decode(<span class="string">'base64'</span>).decode(<span class="string">'bz2'</span>).decode(<span class="string">'utf-8'</span>)</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">to_python</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            <span class="keyword">return</span> value.decode(<span class="string">'base64'</span>).decode(<span class="string">'bz2'</span>).decode(<span class="string">'utf-8'</span>)</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_prep_value</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            value.decode(<span class="string">'base64'</span>)</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                <span class="keyword">return</span> value.encode(<span class="string">'utf-8'</span>).encode(<span class="string">'bz2'</span>).encode(<span class="string">'base64'</span>)</span><br><span class="line">            <span class="keyword">except</span> Exception:</span><br><span class="line">                <span class="keyword">return</span> value</span><br><span class="line">Django <span class="number">1.8</span>及以上版本中，from_db_value 函数用于转化数据库中的字符到 Python的变量。</span><br></pre></td></tr></table></figure><p>2、保存一个 列表到数据库中，在读取用的时候要是 Python的列表的形式，我们来自己写一个 ListField</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">这个ListField继承自 TextField，代码如下：</span><br><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line"><span class="keyword">import</span> ast</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ListField</span><span class="params">(models.TextField)</span>:</span></span><br><span class="line">    __metaclass__ = models.SubfieldBase</span><br><span class="line">    description = <span class="string">"Stores a python list"</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, *args, **kwargs)</span>:</span></span><br><span class="line">        super(ListField, self).__init__(*args, **kwargs)</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">to_python</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> value:</span><br><span class="line">            value = []</span><br><span class="line"> </span><br><span class="line">        <span class="keyword">if</span> isinstance(value, list):</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">        <span class="keyword">return</span> ast.literal_eval(value)</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_prep_value</span><span class="params">(self, value)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> value <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line"> </span><br><span class="line">        <span class="keyword">return</span> unicode(value) <span class="comment"># use str(value) in Python 3</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">value_to_string</span><span class="params">(self, obj)</span>:</span></span><br><span class="line">        value = self._get_val_from_obj(obj)</span><br><span class="line">        <span class="keyword">return</span> self.get_db_prep_value(value)</span><br><span class="line"> 使用它很简单，首先导入 ListField，像自带的 Field 一样使用:</span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">Article</span><span class="params">(models.Model)</span>:</span></span><br><span class="line">    labels = ListField()</span><br></pre></td></tr></table></figure><h4 id="九-django-queryset-api"><a class="markdownIt-Anchor" href="#九-django-queryset-api"></a> 九、Django QuerySet API</h4><p>1、QuerySet 创建对象的方法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> blog.models <span class="keyword">import</span> Blog</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b = Blog(name=<span class="string">'Beatles Blog'</span>, tagline=<span class="string">'All the latest Beatles news.'</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b.save()</span><br><span class="line"> </span><br><span class="line">总之，一共有四种方法</span><br><span class="line"><span class="comment"># 方法 1</span></span><br><span class="line">Author.objects.create(name=<span class="string">"WeizhongTu"</span>, email=<span class="string">"tuweizhong@163.com"</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 方法 2</span></span><br><span class="line">twz = Author(name=<span class="string">"WeizhongTu"</span>, email=<span class="string">"tuweizhong@163.com"</span>)</span><br><span class="line">twz.save()</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 方法 3</span></span><br><span class="line">twz = Author()</span><br><span class="line">twz.name=<span class="string">"WeizhongTu"</span></span><br><span class="line">twz.email=<span class="string">"tuweizhong@163.com"</span></span><br><span class="line">twz.save()</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 方法 4，首先尝试获取，不存在就创建，可以防止重复</span></span><br><span class="line">Author.objects.get_or_create(name=<span class="string">"WeizhongTu"</span>, email=<span class="string">"tuweizhong@163.com"</span>)</span><br><span class="line"><span class="comment"># 返回值(object, True/False)</span></span><br><span class="line">注意：</span><br><span class="line">前三种方法返回的都是对应的 object，最后一种方法返回的是一个元组，(object, <span class="literal">True</span>/<span class="literal">False</span>)，创建时返回 <span class="literal">True</span>, 已经存在时返回 <span class="literal">False</span></span><br><span class="line">当有一对多，多对一，或者多对多的关系的时候，先把相关的对象查询出来</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> blog.models <span class="keyword">import</span> Entry</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>entry = Entry.objects.get(pk=<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>cheese_blog = Blog.objects.get(name=<span class="string">"Cheddar Talk"</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>entry.blog = cheese_blog</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>entry.save()</span><br></pre></td></tr></table></figure><p>2、获取对象方法见模型</p><p>3、QuerySet 是可迭代的，</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">es = Entry.objects.all()</span><br><span class="line"><span class="keyword">for</span> e <span class="keyword">in</span> es:</span><br><span class="line">    print(e.headline)</span><br><span class="line">Entry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目。</span><br><span class="line"></span><br><span class="line">注意事项：</span><br><span class="line">(<span class="number">1</span>). 如果只是检查 Entry 中是否有对象，应该用 Entry.objects.all().exists()</span><br><span class="line">(<span class="number">2</span>). QuerySet 支持切片 Entry.objects.all()[:<span class="number">10</span>] 取出<span class="number">10</span>条，可以节省内存</span><br><span class="line">(<span class="number">3</span>). 用 len(es) 可以得到Entry的数量，但是推荐用 Entry.objects.count()来查询数量，后者用的是SQL：SELECT COUNT(*)</span><br><span class="line">(<span class="number">4</span>). list(es) 可以强行将 QuerySet 变成 列表</span><br></pre></td></tr></table></figure><p>4、QuerySet 是可以用pickle序列化到硬盘再读取出来的</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> pickle</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>query = pickle.loads(s)     <span class="comment"># Assuming 's' is the pickled string.</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>qs = MyModel.objects.all()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>qs.query = query            <span class="comment"># Restore the original 'query'.</span></span><br></pre></td></tr></table></figure><p>5、QuerySet 查询结果排序</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Author.objects.all().order_by(&apos;name&apos;)</span><br><span class="line">Author.objects.all().order_by(&apos;-name&apos;) # 在 column name 前加一个负号，可以实现倒序</span><br></pre></td></tr></table></figure><p>6、QuerySet 支持链式查询</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Author.objects.filter(name__contains=&quot;WeizhongTu&quot;).filter(email=&quot;tuweizhong@163.com&quot;)</span><br><span class="line">Author.objects.filter(name__contains=&quot;Wei&quot;).exclude(email=&quot;tuweizhong@163.com&quot;)</span><br><span class="line"> </span><br><span class="line"># 找出名称含有abc, 但是排除年龄是23岁的</span><br><span class="line">Person.objects.filter(name__contains=&quot;abc&quot;).exclude(age=23)</span><br></pre></td></tr></table></figure><p>7、QuerySet 不支持负索引</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Person.objects.all()[:10] 切片操作，前10条</span><br><span class="line">Person.objects.all()[-10:] 会报错！！！</span><br><span class="line"> </span><br><span class="line"># 1. 使用 reverse() 解决</span><br><span class="line">Person.objects.all().reverse()[:2] # 最后两条</span><br><span class="line">Person.objects.all().reverse()[0] # 最后一条</span><br><span class="line"> </span><br><span class="line"># 2. 使用 order_by，在栏目名（column name）前加一个负号</span><br><span class="line">Author.objects.order_by(&apos;-id&apos;)[:20] # id最大的20条</span><br></pre></td></tr></table></figure><p>8、QuerySet 重复的问题，使用 .distinct() 去重</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">一般的情况下，QuerySet 中不会出来重复的，重复是很罕见的，但是当跨越多张表进行检索后，结果并到一起，可以会出来重复的值</span><br><span class="line">qs1 = Pathway.objects.filter(label__name=<span class="string">'x'</span>)</span><br><span class="line">qs2 = Pathway.objects.filter(reaction__name=<span class="string">'A + B &gt;&gt; C'</span>)</span><br><span class="line">qs3 = Pathway.objects.filter(inputer__name=<span class="string">'WeizhongTu'</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 合并到一起</span></span><br><span class="line">qs = qs1 | qs2 | qs3</span><br><span class="line">这个时候就有可能出现重复的</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 去重方法</span></span><br><span class="line">qs = qs.distinct()</span><br></pre></td></tr></table></figure><p>9、查看 Django queryset 执行的 SQL</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">print</span> str(Author.objects.all().query)</span><br><span class="line"><span class="keyword">print</span> str(Author.objects.filter(name=<span class="string">"WeizhongTu"</span>).query)</span><br></pre></td></tr></table></figure><p>10、values_list 获取元组形式结果</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">authors = Author.objects.values_list(<span class="string">'name'</span>, <span class="string">'qq'</span>)</span><br><span class="line">list(authors)</span><br><span class="line">如果只需要 <span class="number">1</span> 个字段，可以指定 flat=<span class="literal">True</span></span><br><span class="line">Author.objects.values_list(<span class="string">'name'</span>, flat=<span class="literal">True</span>)</span><br><span class="line">list(Author.objects.values_list(<span class="string">'name'</span>, flat=<span class="literal">True</span>))</span><br><span class="line">查询 twz915 这个人的文章标题</span><br><span class="line">Article.objects.filter(author__name=<span class="string">'twz915'</span>).values_list(<span class="string">'title'</span>, flat=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure><p>11、values 获取字典形式的结果</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>、比如我们要获取作者的 name 和 qq</span><br><span class="line">Author.objects.values(<span class="string">'name'</span>, <span class="string">'qq'</span>)</span><br></pre></td></tr></table></figure><p>注意：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. values_list 和 values 返回的并不是真正的 列表 或 字典，也是 queryset，他们也是 lazy evaluation 的（惰性评估，通俗地说，就是用的时候才真正的去数据库查）</span><br><span class="line">2. 如果查询后没有使用，在数据库更新后再使用，你发现得到在是新内容！！！如果想要旧内容保持着，数据库更新后不要变，可以 list 一下</span><br><span class="line">3. 如果只是遍历这些结果，没有必要 list 它们转成列表（浪费内存，数据量大的时候要更谨慎！！！）</span><br></pre></td></tr></table></figure><p>12、extra 实现 别名，条件，排序等</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">extra 中可实现别名，条件，排序等，后面两个用 filter, exclude 一般都能实现，排序用 order_by 也能实现。</span><br><span class="line">SELECT name AS tag_name FROM blog_tag;可用select来实现：</span><br><span class="line">tags = Tag.objects.all().extra(select=&#123;<span class="string">'tag_name'</span>: <span class="string">'name'</span>&#125;)</span><br><span class="line">确认一下执行的 SQL：</span><br><span class="line">Tag.objects.all().extra(select=&#123;<span class="string">'tag_name'</span>: <span class="string">'name'</span>&#125;).query.__str__()</span><br><span class="line">可以用 defer 排除掉原来的 name：</span><br><span class="line">Tag.objects.all().extra(select=&#123;<span class="string">'tag_name'</span>: <span class="string">'name'</span>&#125;).defer(<span class="string">'name'</span>).query.__str__()</span><br></pre></td></tr></table></figure><p>13、annotate 聚合 计数，求和，平均数等</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">1、计数</span><br><span class="line">from django.db.models import Count</span><br><span class="line">Article.objects.all().values(&apos;author_id&apos;).annotate(count=Count(&apos;author&apos;)).values(&apos;author_id&apos;, &apos;count&apos;)</span><br><span class="line">查看执行的sql</span><br><span class="line">Article.objects.all().values(&apos;author_id&apos;).annotate(count=Count(&apos;author&apos;)).values(&apos;author_id&apos;, &apos;count&apos;).query.__str__()</span><br><span class="line">获取作者的名称 及 作者的文章数</span><br><span class="line">Article.objects.all().values(&apos;author__name&apos;).annotate(count=Count(&apos;author&apos;)).values(&apos;author__name&apos;, &apos;count&apos;)</span><br><span class="line">2、求和 与 平均值</span><br><span class="line">求一个作者的所有文章的得分(score)平均值</span><br><span class="line">from django.db.models import Avg</span><br><span class="line">Article.objects.values(&apos;author_id&apos;).annotate(avg_score=Avg(&apos;score&apos;)).values(&apos;author_id&apos;, &apos;avg_score&apos;)</span><br><span class="line">求一个作者所有文章的总分</span><br><span class="line">from django.db.models import Sum</span><br><span class="line">Article.objects.values(&apos;author__name&apos;).annotate(sum_score=Sum(&apos;score&apos;)).values(&apos;author__name&apos;, &apos;sum_score&apos;)</span><br></pre></td></tr></table></figure><p>14、select_related 优化一对一，多对一查询,select_related 是使用 SQL JOIN 一次性取出相关的内容</p><p>修改一个 <a href="http://settings.py" target="_blank" rel="noopener">settings.py</a> 让Django打印出在数据库中执行的语句</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">settings.py 尾部加上,当 DEBUG 为 True 的时候，我们可以看出 django 执行了什么 SQL 语句</span><br><span class="line">LOGGING = &#123;</span><br><span class="line">    &apos;version&apos;: 1,</span><br><span class="line">    &apos;disable_existing_loggers&apos;: False,</span><br><span class="line">    &apos;handlers&apos;: &#123;</span><br><span class="line">        &apos;console&apos;: &#123;</span><br><span class="line">            &apos;class&apos;: &apos;logging.StreamHandler&apos;,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &apos;loggers&apos;: &#123;</span><br><span class="line">        &apos;django.db.backends&apos;: &#123;</span><br><span class="line">            &apos;handlers&apos;: [&apos;console&apos;],</span><br><span class="line">            &apos;level&apos;: &apos;DEBUG&apos; if DEBUG else &apos;INFO&apos;,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">查询文章的时候连同作者一起查询出来，“文章”和“作者”的关系就是多对一，换句说说，就是一篇文章只可能有一个作者</span><br><span class="line">articles = Article.objects.all().select_related(&apos;author&apos;)[:10]</span><br></pre></td></tr></table></figure><p>15、prefetch_related 优化一对多，多对多查询,prefetch_related是通过再执行一条额外的SQL语句，然后用 Python 把两次SQL查询的内容关联（joining)到一起</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">查询文章的同时，查询文章对应的标签。“文章”与“标签”是多对多的关系。</span><br><span class="line">articles = Article.objects.all().prefetch_related(&apos;tags&apos;)[:10]</span><br></pre></td></tr></table></figure><p>16、defer 排除不需要的字段</p><p>在复杂的情况下，表中可能有些字段内容非常多，取出来转化成 Python 对象会占用大量的资源。这时候可以用 defer 来排除这些字段。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Article.objects.all().defer(&apos;content&apos;)</span><br></pre></td></tr></table></figure><p>17、only 仅选择需要的字段</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Author.objects.all().only(&apos;name&apos;)</span><br></pre></td></tr></table></figure><p>18、自定义聚合功能</p><p>实现 GROUP_CONCAT 功能,用来聚合时将符合某分组条件(group by)的不同的值，连到一起，作为整体返回。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">from django.db.models import Aggregate, CharField</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line">class GroupConcat(Aggregate):</span><br><span class="line">    function = &apos;GROUP_CONCAT&apos;</span><br><span class="line">    template = &apos;%(function)s(%(distinct)s%(expressions)s%(ordering)s%(separator)s)&apos;</span><br><span class="line"> </span><br><span class="line">    def __init__(self, expression, distinct=False, ordering=None, separator=&apos;,&apos;, **extra):</span><br><span class="line">        super(GroupConcat, self).__init__(</span><br><span class="line">            expression,</span><br><span class="line">            distinct=&apos;DISTINCT &apos; if distinct else &apos;&apos;,</span><br><span class="line">            ordering=&apos; ORDER BY %s&apos; % ordering if ordering is not None else &apos;&apos;,</span><br><span class="line">            separator=&apos; SEPARATOR &quot;%s&quot;&apos; % separator,</span><br><span class="line">            output_field=CharField(),</span><br><span class="line">            **extra        </span><br><span class="line">            )</span><br><span class="line">想把 level, info 一样的 聚到到一起，按时间和发生次数倒序排列，并含有每次日志发生的时间</span><br><span class="line">ErrorLogModel.objects.values(&apos;level&apos;, &apos;info&apos;).annotate(</span><br><span class="line">    count=Count(1), time=GroupConcat(&apos;time&apos;, ordering=&apos;time DESC&apos;, separator=&apos; | &apos;)</span><br><span class="line">).order_by(&apos;-time&apos;, &apos;-count&apos;)</span><br></pre></td></tr></table></figure><h4 id="十-django数据批量导入"><a class="markdownIt-Anchor" href="#十-django数据批量导入"></a> 十、Django数据批量导入</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>、脚本导入方法</span><br><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment">#coding:utf-8</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.environ.setdefault(<span class="string">"DJANGO_SETTINGS_MODULE"</span>, <span class="string">"mysite.settings"</span>)</span><br><span class="line"><span class="keyword">import</span> django</span><br><span class="line"><span class="keyword">if</span> django.VERSION &gt;= (<span class="number">1</span>, <span class="number">7</span>):<span class="comment">#自动判断版本</span></span><br><span class="line">    django.setup()</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line">    <span class="keyword">from</span> blog.models <span class="keyword">import</span> Blog</span><br><span class="line">    f = open(<span class="string">'oldblog.txt'</span>)</span><br><span class="line">    <span class="keyword">for</span> line <span class="keyword">in</span> f:</span><br><span class="line">        title,content = line.split(<span class="string">'****'</span>)</span><br><span class="line">        Blog.objects.create(title=title,content=content)</span><br><span class="line">    f.close()</span><br><span class="line"> </span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">    main()</span><br><span class="line">    print(<span class="string">'Done!'</span>)</span><br><span class="line">导入数据重复 解决办法：</span><br><span class="line">将上面的Blog.objects.create(title=title,content=content)替换为：Blog.objects.get_or_create(title=title,content=content) </span><br><span class="line">返回值是（BlogObject, <span class="literal">True</span>/<span class="literal">False</span>) 新建时返回 <span class="literal">True</span>, 已经存在时返回 <span class="literal">False</span>。</span><br><span class="line"></span><br><span class="line"><span class="number">2</span>、用fixture导入</span><br><span class="line">fixture文件就是用python manage.py dumpdata 导出的文件</span><br><span class="line">也可以根据自己的models,创建这样的json文件,然后用 python manage.py loaddata fixture.json 导入</span><br><span class="line"></span><br><span class="line"><span class="number">3</span>、Model.objects.bulk_create() 更快更方便</span><br><span class="line">由于Blog.objects.create()每保存一条就执行一次SQL，而bulk_create()是执行一条SQL存入多条数据，做会快很多！</span><br><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.environ.setdefault(<span class="string">"DJANGO_SETTINGS_MODULE"</span>, <span class="string">"mysite.settings"</span>)</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line">    <span class="keyword">from</span> blog.models <span class="keyword">import</span> Blog</span><br><span class="line">    f = open(<span class="string">'oldblog.txt'</span>)</span><br><span class="line">    BlogList = []</span><br><span class="line">    <span class="keyword">for</span> line <span class="keyword">in</span> f:</span><br><span class="line">        title,content = line.split(<span class="string">'****'</span>)</span><br><span class="line">        blog = Blog(title=title,content=content)</span><br><span class="line">        BlogList.append(blog)</span><br><span class="line">    f.close()</span><br><span class="line">     </span><br><span class="line">    Blog.objects.bulk_create(BlogList)</span><br><span class="line"> </span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">    main()</span><br><span class="line">    print(<span class="string">'Done!'</span>)</span><br><span class="line">    </span><br><span class="line">用列表解析代替 <span class="keyword">for</span> 循环会更快！！</span><br><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.environ.setdefault(<span class="string">"DJANGO_SETTINGS_MODULE"</span>, <span class="string">"mysite.settings"</span>)</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line">    <span class="keyword">from</span> blog.models <span class="keyword">import</span> Blog</span><br><span class="line">    f = open(<span class="string">'oldblog.txt'</span>)</span><br><span class="line">     </span><br><span class="line">    BlogList = []</span><br><span class="line">    <span class="keyword">for</span> line <span class="keyword">in</span> f:</span><br><span class="line">        parts = line.split(<span class="string">'****'</span>)</span><br><span class="line">        BlogList.append(Blog(title=parts[<span class="number">0</span>], content=parts[<span class="number">1</span>]))</span><br><span class="line">     </span><br><span class="line">    f.close()</span><br><span class="line">         </span><br><span class="line">    <span class="comment"># 以上四行 也可以用 列表解析 写成下面这样</span></span><br><span class="line">    <span class="comment"># BlogList = [Blog(title=line.split('****')[0], content=line.split('****')[1]) for line in f]</span></span><br><span class="line">     </span><br><span class="line">    Blog.objects.bulk_create(BlogList)</span><br><span class="line"> </span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">    main()</span><br><span class="line">    print(<span class="string">'Done!'</span>)</span><br></pre></td></tr></table></figure><h4 id="十一-django后台"><a class="markdownIt-Anchor" href="#十一-django后台"></a> 十一、Django后台</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">修改admin.py，没有则创建一个。</span><br><span class="line">from django.contrib import admin</span><br><span class="line">from .models import Article</span><br><span class="line">admin.site.register(Article)</span><br></pre></td></tr></table></figure><p>为保证后台显示不同的名称，可以models定义中增加<code>__unicode__</code>函数:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding:utf-8</span></span><br><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Article</span><span class="params">(models.Model)</span>:</span></span><br><span class="line">    title = models.CharField(<span class="string">u'标题'</span>, max_length=<span class="number">256</span>)</span><br><span class="line">    content = models.TextField(<span class="string">u'内容'</span>)</span><br><span class="line">    pub_date = models.DateTimeField(<span class="string">u'发表时间'</span>, auto_now_add=<span class="literal">True</span>, editable = <span class="literal">True</span>)</span><br><span class="line">    update_time = models.DateTimeField(<span class="string">u'更新时间'</span>,auto_now=<span class="literal">True</span>, null=<span class="literal">True</span>)</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__unicode__</span><span class="params">(self)</span>:</span><span class="comment"># 在Python3中用 __str__ 代替 __unicode__</span></span><br><span class="line">        <span class="keyword">return</span> self.title</span><br><span class="line">    兼容python2.x和python3.x：</span><br><span class="line">    <span class="comment"># coding:utf-8</span></span><br><span class="line">	<span class="keyword">from</span> __future__ <span class="keyword">import</span> unicode_literals</span><br><span class="line">	<span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line">	<span class="keyword">from</span> django.utils.encoding <span class="keyword">import</span> python_2_unicode_compatible</span><br><span class="line"> 	</span><br><span class="line"><span class="meta">	@python_2_unicode_compatible</span></span><br><span class="line">	<span class="class"><span class="keyword">class</span> <span class="title">Article</span><span class="params">(models.Model)</span>:</span></span><br><span class="line">    	title = models.CharField(<span class="string">'标题'</span>, max_length=<span class="number">256</span>)</span><br><span class="line">    	content = models.TextField(<span class="string">'内容'</span>)</span><br><span class="line"> 		pub_date = models.DateTimeField(<span class="string">'发表时间'</span>, auto_now_add=<span class="literal">True</span>, editable = <span class="literal">True</span>)</span><br><span class="line">    	update_time = models.DateTimeField(<span class="string">'更新时间'</span>,auto_now=<span class="literal">True</span>, null=<span class="literal">True</span>)</span><br><span class="line"> 		<span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line">        	<span class="keyword">return</span> self.title</span><br><span class="line">python_2_unicode_compatible 会自动做一些处理去适应python不同的版本，本例中的 unicode_literals 可以让python2.x 也像 python3 那个处理 unicode 字符，以便有更好地兼容性。</span><br></pre></td></tr></table></figure><p>在列表显示与字段相关的其它内容</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> .models <span class="keyword">import</span> Article</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    list_display = (<span class="string">'title'</span>,<span class="string">'pub_date'</span>,<span class="string">'update_time'</span>,)</span><br><span class="line"> </span><br><span class="line">admin.site.register(Article,ArticleAdmin)</span><br><span class="line">list_display 就是来配置要显示的字段的，当然也可以显示非字段内容，或者字段相关的内容,比如：</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span><span class="params">(models.Model)</span>:</span></span><br><span class="line">    first_name = models.CharField(max_length=<span class="number">50</span>)</span><br><span class="line">    last_name = models.CharField(max_length=<span class="number">50</span>)</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">my_property</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> self.first_name + <span class="string">' '</span> + self.last_name</span><br><span class="line">    my_property.short_description = <span class="string">"Full name of the person"</span></span><br><span class="line"> </span><br><span class="line">    full_name = property(my_property)</span><br><span class="line">在admin.py中：</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> .models <span class="keyword">import</span> Article, Person</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    list_display = (<span class="string">'title'</span>, <span class="string">'pub_date'</span>, <span class="string">'update_time'</span>,)</span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">PersonAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    list_display = (<span class="string">'full_name'</span>,)</span><br><span class="line"> </span><br><span class="line">admin.site.register(Article, ArticleAdmin)</span><br><span class="line">admin.site.register(Person, PersonAdmin)</span><br></pre></td></tr></table></figure><p>对django admin site进行修改以满足自己的需求</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>、定制加载的列表, 根据不同的人显示不同的内容列表，该类实现的功能是如果是超级管理员就列出所有的，如果不是，就仅列出访问者自己相关的</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyModelAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_queryset</span><span class="params">(self, request)</span>:</span></span><br><span class="line">        qs = super(MyModelAdmin, self).get_queryset(request)</span><br><span class="line">        <span class="keyword">if</span> request.user.is_superuser:</span><br><span class="line">            <span class="keyword">return</span> qs</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> qs.filter(author=request.user)</span><br><span class="line"><span class="number">2</span>、.定制搜索功能（django <span class="number">1.6</span>及以上才有)，queryset 是默认的结果，search_term 是在后台搜索的关键词。</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PersonAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    list_display = (<span class="string">'name'</span>, <span class="string">'age'</span>)</span><br><span class="line">    search_fields = (<span class="string">'name'</span>,)</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_search_results</span><span class="params">(self, request, queryset, search_term)</span>:</span></span><br><span class="line">        queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term)</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            search_term_as_int = int(search_term)</span><br><span class="line">            queryset |= self.model.objects.filter(age=search_term_as_int)</span><br><span class="line">        <span class="keyword">except</span>:</span><br><span class="line">            <span class="keyword">pass</span></span><br><span class="line">        <span class="keyword">return</span> queryset, use_distinct</span><br><span class="line"><span class="number">3</span>、修改保存时的一些操作，可以检查用户，保存的内容等。其中obj是修改后的对象，form是返回的表单（修改后的），当新建一个对象时 change = <span class="literal">False</span>, 当修改一个对象时 change = <span class="literal">True</span></span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">save_model</span><span class="params">(self, request, obj, form, change)</span>:</span></span><br><span class="line">        obj.user = request.user</span><br><span class="line">        obj.save()</span><br><span class="line">需要获取修改前的对象的内容可以用</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">save_model</span><span class="params">(self, request, obj, form, change)</span>:</span></span><br><span class="line">        obj_original = self.model.objects.get(pk=obj.pk)</span><br><span class="line">        obj.user = request.user</span><br><span class="line">        obj.save()</span><br><span class="line">优化后：</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">save_model</span><span class="params">(self, request, obj, form, change)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> change:<span class="comment"># 更改的时候</span></span><br><span class="line">            obj_original = self.model.objects.get(pk=obj.pk)</span><br><span class="line">        <span class="keyword">else</span>:<span class="comment"># 新增的时候</span></span><br><span class="line">            obj_original = <span class="literal">None</span></span><br><span class="line"> </span><br><span class="line">        obj.user = request.user</span><br><span class="line">        obj.save()</span><br><span class="line"></span><br><span class="line"><span class="number">4</span>、 删除时做一些处理</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleAdmin</span><span class="params">(admin.ModelAdmin)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">delete_model</span><span class="params">(self, request, obj)</span>:</span></span><br><span class="line">        <span class="string">"""</span></span><br><span class="line"><span class="string">        Given a model instance delete it from the database.</span></span><br><span class="line"><span class="string">        """</span></span><br><span class="line">        <span class="comment"># handle something here</span></span><br><span class="line">        obj.delete()</span><br></pre></td></tr></table></figure><h4 id="十二-django的forms表单"><a class="markdownIt-Anchor" href="#十二-django的forms表单"></a> 十二、Django的forms表单</h4><p>1、表单的创建</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">在app中新建一个forms.py的文件，</span><br><span class="line"><span class="keyword">from</span> django <span class="keyword">import</span> forms</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">AddForm</span><span class="params">(forms.Form)</span>:</span></span><br><span class="line">    a = forms.IntegerField()</span><br><span class="line">    b = forms.IntegerField()</span><br><span class="line">在视图函数 views.py 中</span><br><span class="line"><span class="comment"># coding:utf-8</span></span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render</span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 引入我们创建的表单类</span></span><br><span class="line"><span class="keyword">from</span> .forms <span class="keyword">import</span> AddForm</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:<span class="comment"># 当提交表单时</span></span><br><span class="line">        form = AddForm(request.POST) <span class="comment"># form 包含提交的数据</span></span><br><span class="line">        <span class="keyword">if</span> form.is_valid():<span class="comment"># 如果提交的数据合法</span></span><br><span class="line">            a = form.cleaned_data[<span class="string">'a'</span>]</span><br><span class="line">            b = form.cleaned_data[<span class="string">'b'</span>]</span><br><span class="line">            <span class="keyword">return</span> HttpResponse(str(int(a) + int(b)))</span><br><span class="line">     <span class="keyword">else</span>:<span class="comment"># 当正常访问时</span></span><br><span class="line">        form = AddForm()</span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'index.html'</span>, &#123;<span class="string">'form'</span>: form&#125;)</span><br><span class="line">对应的模板文件 index.html</span><br><span class="line">&lt;form method=<span class="string">'post'</span>&gt;</span><br><span class="line">&#123;% csrf_token %&#125;</span><br><span class="line">&#123;&#123; form &#125;&#125;</span><br><span class="line">&lt;input type=<span class="string">"submit"</span> value=<span class="string">"提交"</span>&gt;</span><br><span class="line">&lt;/form&gt;</span><br><span class="line">在 urls.py 中对应写上这个函数</span><br><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> patterns, include, url</span><br><span class="line"> <span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line">admin.autodiscover()</span><br><span class="line"> </span><br><span class="line">urlpatterns = patterns(<span class="string">''</span>,</span><br><span class="line">    <span class="comment"># 注意下面这一行</span></span><br><span class="line">    url(<span class="string">r'^$'</span>, <span class="string">'tools.views.index'</span>, name=<span class="string">'home'</span>),</span><br><span class="line">    url(<span class="string">r'^admin/'</span>, include(admin.site.urls)),</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h4 id="十三-django配置"><a class="markdownIt-Anchor" href="#十三-django配置"></a> 十三、Django配置</h4><p>1、基本目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">import os</span><br><span class="line">BASE_DIR = os.path.dirname(os.path.dirname(__file__))</span><br><span class="line"> __file__ 这个变量可以获取到当前文件（包含这个代码的文件）的路径；</span><br><span class="line"> os.path.dirname(__file__) 得到文件所在目录；</span><br><span class="line"> 再来一个os.path.dirname()就是目录的上一级，BASE_DIR 即为项目所在目录。</span><br></pre></td></tr></table></figure><p>2、开启debug</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">DEBUG = True</span><br><span class="line">TEMPLATE_DEBUG = True</span><br><span class="line">DEBUG＝True 时，如果出现 bug 便于我们看见问题所在</span><br></pre></td></tr></table></figure><p>3、设置哪些域名可以访问,即使在 Apache 或 Nginx 等中绑定了，这里不允许的话，也是不能访问的.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ALLOWED_HOSTS = [&apos;*.besttome.com&apos;,&apos;www.ziqiangxuetang.com&apos;]</span><br><span class="line">当 DEBUG=False 时，这个为必填项，如果不想输入，可以用 ALLOW_HOSTS = [&apos;*&apos;] 来允许所有的</span><br></pre></td></tr></table></figure><p>4、指定静态文件目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">STATIC_URL = &apos;/static/&apos;     #static 是静态文件所有目录，比如 jquery.js, bootstrap.min.css 等文件</span><br><span class="line">STATIC_ROOT = os.path.join(BASE_DIR,&apos;static&apos;)</span><br><span class="line">有一些共用的静态文件，这时候可以设置 STATICFILES_DIRS 另外弄一个文件夹,就可以把静态文件放在 common_static 和 /var/www/static/中了，Django也能找到它们</span><br><span class="line">STATICFILES_DIRS = (</span><br><span class="line">    os.path.join(BASE_DIR, &quot;common_static&quot;),</span><br><span class="line">    &apos;/var/www/static/&apos;,</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>5、上传文件目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">MEDIA_URL = &apos;/media/&apos;</span><br><span class="line">MEDIA_ROOT = os.path.join(BASE_DIR,&apos;media&apos;)</span><br><span class="line">media文件夹用来存放用户上传的文件，与权限有关</span><br></pre></td></tr></table></figure><p>6、添加临时模版</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Django 1.5 - Django 1.7版本</span><br><span class="line">TEMPLATE_DIRS = (</span><br><span class="line">    os.path.join(BASE_DIR, &apos;templates&apos;).replace(&apos;\\&apos;, &apos;/&apos;),</span><br><span class="line">    os.path.join(BASE_DIR, &apos;templates2&apos;).replace(&apos;\\&apos;, &apos;/&apos;),</span><br><span class="line">    # ...</span><br><span class="line">)</span><br><span class="line">Django 1.8 及以上版本</span><br><span class="line">TEMPLATES = [</span><br><span class="line">    &#123;</span><br><span class="line">        &apos;BACKEND&apos;: &apos;django.template.backends.django.DjangoTemplates&apos;,</span><br><span class="line">        &apos;DIRS&apos;: [</span><br><span class="line">            os.path.join(BASE_DIR,&apos;templates&apos;).replace(&apos;\\&apos;, &apos;/&apos;),</span><br><span class="line">            os.path.join(BASE_DIR,&apos;templates2&apos;).replace(&apos;\\&apos;, &apos;/&apos;),</span><br><span class="line">        ],</span><br><span class="line">        &apos;APP_DIRS&apos;: True,</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h4 id="十四-django发送邮件"><a class="markdownIt-Anchor" href="#十四-django发送邮件"></a> 十四、Django发送邮件</h4><p>1、配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">在 settings.py 的最后面加上这些</span><br><span class="line">EMAIL_BACKEND = &apos;django.core.mail.backends.smtp.EmailBackend&apos;</span><br><span class="line">  </span><br><span class="line">EMAIL_USE_TLS = False</span><br><span class="line">EMAIL_HOST = &apos;smtp.tuweizhong.com&apos;</span><br><span class="line">EMAIL_PORT = 25</span><br><span class="line">EMAIL_HOST_USER = &apos;mail@tuweizhong.com&apos;</span><br><span class="line">EMAIL_HOST_PASSWORD = &apos;xxxx&apos;</span><br><span class="line">DEFAULT_FROM_EMAIL = &apos;mail@tuweizhong.com&apos;</span><br><span class="line">DEFAULT_FROM_EMAIL 还可以写成这样：</span><br><span class="line">DEFAULT_FROM_EMAIL = &apos;tuweizhong &lt;tuweizhong@163.com&gt;&apos;</span><br><span class="line">163邮箱、126邮箱容易连接报错，不建议使用</span><br></pre></td></tr></table></figure><p>2、发送</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.core.mail <span class="keyword">import</span> send_mail</span><br><span class="line"> </span><br><span class="line">send_mail(<span class="string">'Subject here'</span>, <span class="string">'Here is the message.'</span>, <span class="string">'from@example.com'</span>,</span><br><span class="line">    [<span class="string">'to@example.com'</span>], fail_silently=<span class="literal">False</span>)</span><br><span class="line">一次性发送多个邮件：</span><br><span class="line"><span class="keyword">from</span> django.core.mail <span class="keyword">import</span> send_mass_mail</span><br><span class="line"> </span><br><span class="line">message1 = (<span class="string">'Subject here'</span>, <span class="string">'Here is the message'</span>, <span class="string">'from@example.com'</span>, [<span class="string">'first@example.com'</span>, <span class="string">'other@example.com'</span>])</span><br><span class="line">message2 = (<span class="string">'Another Subject'</span>, <span class="string">'Here is another message'</span>, <span class="string">'from@example.com'</span>, [<span class="string">'second@test.com'</span>])</span><br><span class="line">send_mass_mail((message1, message2), fail_silently=<span class="literal">False</span>)</span><br><span class="line">备注：send_mail 每次发邮件都会建立一个连接，发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件，所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。</span><br></pre></td></tr></table></figure><p>3、在邮件中添加附件，发送 html 格式的内容</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf <span class="keyword">import</span> settings</span><br><span class="line"><span class="keyword">from</span> django.core.mail <span class="keyword">import</span> EmailMultiAlternatives</span><br><span class="line"></span><br><span class="line">from_email = settings.DEFAULT_FROM_EMAIL</span><br><span class="line"><span class="comment"># subject 主题 content 内容 to_addr 是一个列表，发送给哪些人</span></span><br><span class="line">msg = EmailMultiAlternatives(subject, content, from_email, [to_addr])</span><br><span class="line">msg.content_subtype = <span class="string">"html"</span></span><br><span class="line"><span class="comment"># 添加附件（可选）</span></span><br><span class="line">msg.attach_file(<span class="string">'./twz.pdf'</span>)</span><br><span class="line"><span class="comment"># 发送</span></span><br><span class="line">msg.send()</span><br><span class="line">为安全起见，你可以弄两个版本，一个纯文本(text/plain)的为默认的，另外再提供一个 html 版本的</span><br><span class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> unicode_literals</span><br><span class="line"> </span><br><span class="line"><span class="keyword">from</span> django.conf <span class="keyword">import</span> settings</span><br><span class="line"><span class="keyword">from</span> django.core.mail <span class="keyword">import</span> EmailMultiAlternatives</span><br><span class="line"> </span><br><span class="line"> subject = <span class="string">'来自自强学堂的问候'</span></span><br><span class="line"> text_content = <span class="string">'这是一封重要的邮件.'</span></span><br><span class="line"> html_content = <span class="string">'&lt;p&gt;这是一封&lt;strong&gt;重要的&lt;/strong&gt;邮件.&lt;/p&gt;'</span></span><br><span class="line"> msg = EmailMultiAlternatives(subject, text_content, from_email, [to@youemail.com])</span><br><span class="line"> msg.attach_alternative(html_content, <span class="string">"text/html"</span>)</span><br><span class="line"> msg.send()</span><br></pre></td></tr></table></figure><h4 id="十五-django多数据库联用"><a class="markdownIt-Anchor" href="#十五-django多数据库联用"></a> 十五、Django多数据库联用</h4><p>1、设置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">在setting中添加</span><br><span class="line">DATABASES = &#123;</span><br><span class="line">    &apos;default&apos;: &#123;</span><br><span class="line">        &apos;ENGINE&apos;: &apos;django.db.backends.sqlite3&apos;,</span><br><span class="line">        &apos;NAME&apos;: os.path.join(BASE_DIR, &apos;db.sqlite3&apos;),</span><br><span class="line">    &#125;,</span><br><span class="line">    &apos;db1&apos;: &#123;</span><br><span class="line">        &apos;ENGINE&apos;: &apos;django.db.backends.postgresql_psycopg2&apos;,</span><br><span class="line">        &apos;NAME&apos;: &apos;dbname1&apos;,</span><br><span class="line">        &apos;USER&apos;: &apos;your_db_user_name&apos;,</span><br><span class="line">        &apos;PASSWORD&apos;: &apos;yourpassword&apos;,</span><br><span class="line">        &quot;HOST&quot;: &quot;localhost&quot;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &apos;db2&apos;: &#123;</span><br><span class="line">        &apos;ENGINE&apos;: &apos;django.db.backends.postgresql_psycopg2&apos;,</span><br><span class="line">        &apos;NAME&apos;: &apos;dbname2&apos;,</span><br><span class="line">        &apos;USER&apos;: &apos;your_db_user_name&apos;,</span><br><span class="line">        &apos;PASSWORD&apos;: &apos;yourpassword&apos;,</span><br><span class="line">        &quot;HOST&quot;: &quot;localhost&quot;,</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"># use multi-database in django</span><br><span class="line"># add by WeizhongTu</span><br><span class="line">DATABASE_ROUTERS = [&apos;project_name.database_router.DatabaseAppsRouter&apos;]</span><br><span class="line">DATABASE_APPS_MAPPING = &#123;</span><br><span class="line">    # example:</span><br><span class="line">    #&apos;app_name&apos;:&apos;database_name&apos;,</span><br><span class="line">    &apos;app1&apos;: &apos;db1&apos;,</span><br><span class="line">    &apos;app2&apos;: &apos;db2&apos;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在项目文件夹中增加一个路由文件database_router.py</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="keyword">from</span> django.conf <span class="keyword">import</span> settings</span><br><span class="line"> </span><br><span class="line">DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DatabaseAppsRouter</span><span class="params">(object)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    A router to control all database operations on models for different</span></span><br><span class="line"><span class="string">    databases.</span></span><br><span class="line"><span class="string"> </span></span><br><span class="line"><span class="string">    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router</span></span><br><span class="line"><span class="string">    will fallback to the `default` database.</span></span><br><span class="line"><span class="string"> </span></span><br><span class="line"><span class="string">    Settings example:</span></span><br><span class="line"><span class="string"> </span></span><br><span class="line"><span class="string">    DATABASE_APPS_MAPPING = &#123;'app1': 'db1', 'app2': 'db2'&#125;</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">db_for_read</span><span class="params">(self, model, **hints)</span>:</span></span><br><span class="line">        <span class="string">""""Point all read operations to the specific database."""</span></span><br><span class="line">        <span class="keyword">if</span> model._meta.app_label <span class="keyword">in</span> DATABASE_MAPPING:</span><br><span class="line">            <span class="keyword">return</span> DATABASE_MAPPING[model._meta.app_label]</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">db_for_write</span><span class="params">(self, model, **hints)</span>:</span></span><br><span class="line">        <span class="string">"""Point all write operations to the specific database."""</span></span><br><span class="line">        <span class="keyword">if</span> model._meta.app_label <span class="keyword">in</span> DATABASE_MAPPING:</span><br><span class="line">            <span class="keyword">return</span> DATABASE_MAPPING[model._meta.app_label]</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">allow_relation</span><span class="params">(self, obj1, obj2, **hints)</span>:</span></span><br><span class="line">        <span class="string">"""Allow any relation between apps that use the same database."""</span></span><br><span class="line">        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)</span><br><span class="line">        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)</span><br><span class="line">        <span class="keyword">if</span> db_obj1 <span class="keyword">and</span> db_obj2:</span><br><span class="line">            <span class="keyword">if</span> db_obj1 == db_obj2:</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">allow_syncdb</span><span class="params">(self, db, model)</span>:</span></span><br><span class="line">        <span class="string">"""Make sure that apps only appear in the related database."""</span></span><br><span class="line"> </span><br><span class="line">        <span class="keyword">if</span> db <span class="keyword">in</span> DATABASE_MAPPING.values():</span><br><span class="line">            <span class="keyword">return</span> DATABASE_MAPPING.get(model._meta.app_label) == db</span><br><span class="line">        <span class="keyword">elif</span> model._meta.app_label <span class="keyword">in</span> DATABASE_MAPPING:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">None</span></span><br></pre></td></tr></table></figure><p>2、使用指定的数据库来执行操作</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">在查询的语句后面用 using(dbname) 来指定要操作的数据库即可</span><br><span class="line"><span class="comment"># 查询</span></span><br><span class="line">YourModel.objects.using(<span class="string">'db1'</span>).all() </span><br><span class="line">或者 YourModel.objects.using(<span class="string">'db2'</span>).all()</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 保存 或 删除</span></span><br><span class="line">user_obj.save(using=<span class="string">'new_users'</span>)</span><br><span class="line">user_obj.delete(using=<span class="string">'legacy_users'</span>)</span><br></pre></td></tr></table></figure><p>3、多个数据库联用时数据导入导出</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">使用的时候和一个数据库的区别是:</span><br><span class="line">如果不是defalut(默认数据库）要在命令后边加 --database=数据库对应的settings.py中的名称  如： --database=db1  或 --database=db2</span><br><span class="line">数据库同步（创建表）:</span><br><span class="line">python manage.py syncdb <span class="comment">#同步默认的数据库，和原来的没有区别</span></span><br><span class="line"><span class="comment">#同步数据库 db1 (注意：不是数据库名是db1,是settings.py中的那个db1，不过你可以使这两个名称相同，容易使用)</span></span><br><span class="line">python manage.py syncdb --database=db1</span><br><span class="line">数据导出:</span><br><span class="line">python manage.py dumpdata app1 --database=db1 &gt; app1_fixture.json</span><br><span class="line">python manage.py dumpdata app2 --database=db2 &gt; app2_fixture.json</span><br><span class="line">python manage.py dumpdata auth &gt; auth_fixture.json</span><br><span class="line">数据库导入:</span><br><span class="line">python manage.py loaddata app1_fixture.json --database=db1</span><br><span class="line">python manage.py loaddata app2_fixture.json --database=db2</span><br></pre></td></tr></table></figure><h4 id="十六-用户注册"><a class="markdownIt-Anchor" href="#十六-用户注册"></a> 十六、用户注册</h4><p>1、urls.py的设置</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> url, include</span><br><span class="line"><span class="keyword">from</span> django.contrib <span class="keyword">import</span> admin</span><br><span class="line"><span class="keyword">from</span> django.contrib.auth <span class="keyword">import</span> urls <span class="keyword">as</span> auth_urls</span><br><span class="line">urlpatterns = [</span><br><span class="line">    url(<span class="string">r'^accounts/'</span>, include(auth_urls, namespace=<span class="string">'accounts'</span>)),</span><br><span class="line">    url(<span class="string">r'^admin/'</span>, admin.site.urls),</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>2、认证包<code>django-users2</code>:<code>https://github.com/mishbahr/django-users2](https://github.com/mishbahr/django-users2</code></p><p>3、django-users2 这个包在 Django 1.5 - Django 1.9 中使用都没有问题</p><p>4、使用方法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">pip install django-users2</span><br><span class="line">把 users 这个 app 加入到 INSTALLED_APPS</span><br><span class="line">INSTALLED_APPS = (</span><br><span class="line">    ...</span><br><span class="line">    <span class="string">'django.contrib.auth'</span>,</span><br><span class="line">    <span class="string">'django.contrib.sites'</span>,</span><br><span class="line">    <span class="string">'users'</span>,</span><br><span class="line">    ...</span><br><span class="line">)</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line">AUTH_USER_MODEL = <span class="string">'users.User'</span>    <span class="comment">#AUTH_USER_MODEL 是替换成自定义的用户认证</span></span><br><span class="line">修改 urls.py</span><br><span class="line">urlpatterns = patterns(<span class="string">''</span>,</span><br><span class="line">    ...</span><br><span class="line">    url(<span class="string">r'^accounts/'</span>, include(<span class="string">'users.urls'</span>)),</span><br><span class="line">    ...</span><br><span class="line">)</span><br><span class="line">同步数据，创建相应的表</span><br><span class="line">python manage.py syncdb</span><br><span class="line"> </span><br><span class="line">Django <span class="number">1.7</span> 及以上</span><br><span class="line">python manage.py makemigrations</span><br><span class="line">python manage.py migrate</span><br><span class="line">配置登陆注册的一些选项，找密码时发邮件的邮箱</span><br><span class="line">在 settings.py 最后面添加;</span><br><span class="line">USERS_REGISTRATION_OPEN = <span class="literal">True</span> </span><br><span class="line">USERS_VERIFY_EMAIL = <span class="literal">True</span> </span><br><span class="line">USERS_AUTO_LOGIN_ON_ACTIVATION = <span class="literal">True</span> </span><br><span class="line">USERS_EMAIL_CONFIRMATION_TIMEOUT_DAYS = <span class="number">3</span> </span><br><span class="line"><span class="comment"># Specifies minimum length for passwords:</span></span><br><span class="line">USERS_PASSWORD_MIN_LENGTH = <span class="number">5</span></span><br><span class="line"><span class="comment"># Specifies maximum length for passwords:</span></span><br><span class="line">USERS_PASSWORD_MAX_LENGTH = <span class="literal">None</span> </span><br><span class="line"><span class="comment"># the complexity validator, checks the password strength</span></span><br><span class="line">USERS_CHECK_PASSWORD_COMPLEXITY = <span class="literal">True</span> </span><br><span class="line">USERS_SPAM_PROTECTION = <span class="literal">False</span>  <span class="comment"># important! </span></span><br><span class="line"><span class="comment">#  ---------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  Email</span></span><br><span class="line">EMAIL_BACKEND = <span class="string">'django.core.mail.backends.smtp.EmailBackend'</span> </span><br><span class="line">EMAIL_USE_TLS = <span class="literal">False</span></span><br><span class="line">EMAIL_HOST = <span class="string">'smtp.tuweizhong.com'</span></span><br><span class="line">EMAIL_PORT = <span class="number">25</span></span><br><span class="line">EMAIL_HOST_USER = <span class="string">'mail@tuweizhong.com'</span></span><br><span class="line">EMAIL_HOST_PASSWORD = <span class="string">'xxxx'</span></span><br><span class="line">DEFAULT_FROM_EMAIL = <span class="string">'mail@tuweizhong.com'</span></span><br><span class="line"><span class="comment">#  ---------------------------------------------------------</span></span><br></pre></td></tr></table></figure><h4 id="十七-django缓存系统"><a class="markdownIt-Anchor" href="#十七-django缓存系统"></a> 十七、Django缓存系统</h4><p>1、缓存系统工作原理</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">对于给定的网址，尝试从缓存中找到网址，如果页面在缓存中，直接返回缓存的页面，如果缓存中没有，一系列操作（比如查数据库）后，保存生成的页面内容到缓存系统以供下一次使用，然后返回生成的页面内容。</span><br></pre></td></tr></table></figure><p>2、缓存的几种方式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"> Django settings 中 cache 默认为:</span><br><span class="line"> &#123;</span><br><span class="line">    <span class="string">'default'</span>: &#123;</span><br><span class="line">        <span class="string">'BACKEND'</span>: <span class="string">'django.core.cache.backends.locmem.LocMemCache'</span>,</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">利用本地的内存来当缓存，速度很快,其它的一些内建可用的 Backends 有:</span><br><span class="line"><span class="string">'django.core.cache.backends.db.DatabaseCache'</span></span><br><span class="line"><span class="string">'django.core.cache.backends.dummy.DummyCache'</span></span><br><span class="line"><span class="string">'django.core.cache.backends.filebased.FileBasedCache'</span></span><br><span class="line"><span class="string">'django.core.cache.backends.locmem.LocMemCache'</span></span><br><span class="line"><span class="string">'django.core.cache.backends.memcached.MemcachedCache'</span></span><br><span class="line"><span class="string">'django.core.cache.backends.memcached.PyLibMCCache'</span></span><br><span class="line">利用文件系统来缓存：</span><br><span class="line">CACHES = &#123;</span><br><span class="line">    <span class="string">'default'</span>: &#123;</span><br><span class="line">        <span class="string">'BACKEND'</span>: <span class="string">'django.core.cache.backends.filebased.FileBasedCache'</span>,</span><br><span class="line">        <span class="string">'LOCATION'</span>: <span class="string">'/var/tmp/django_cache'</span>,</span><br><span class="line">        <span class="string">'TIMEOUT'</span>: <span class="number">600</span>,</span><br><span class="line">        <span class="string">'OPTIONS'</span>: &#123;</span><br><span class="line">            <span class="string">'MAX_ENTRIES'</span>: <span class="number">1000</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">利用数据库来缓存，利用命令创建相应的表：python manage.py createcachetable cache_table_name</span><br><span class="line">CACHES = &#123;</span><br><span class="line">    <span class="string">'default'</span>: &#123;</span><br><span class="line">        <span class="string">'BACKEND'</span>: <span class="string">'django.core.cache.backends.db.DatabaseCache'</span>,</span><br><span class="line">        <span class="string">'LOCATION'</span>: <span class="string">'cache_table_name'</span>,</span><br><span class="line">        <span class="string">'TIMEOUT'</span>: <span class="number">600</span>,</span><br><span class="line">        <span class="string">'OPTIONS'</span>: &#123;</span><br><span class="line">            <span class="string">'MAX_ENTRIES'</span>: <span class="number">2000</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">使用缓存实例：</span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render</span><br><span class="line"><span class="keyword">from</span> django.views.decorators.cache <span class="keyword">import</span> cache_page</span><br><span class="line"> </span><br><span class="line"><span class="meta">@cache_page(60 * 15) # 秒数，这里指缓存 15 分钟，不直接写900是为了提高可读性</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="comment"># 读取数据库等 并渲染到网页</span></span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'index.html'</span>, &#123;<span class="string">'queryset'</span>:queryset&#125;)</span><br></pre></td></tr></table></figure><h4 id="十八-django生成静态页面"><a class="markdownIt-Anchor" href="#十八-django生成静态页面"></a> 十八、Django生成静态页面</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">只要在views.py中这样写就行了</span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render</span><br><span class="line"><span class="keyword">from</span> django.template.loader <span class="keyword">import</span> render_to_string</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">my_view</span><span class="params">(request)</span>:</span></span><br><span class="line">    context = &#123;<span class="string">'some_key'</span>: <span class="string">'some_value'</span>&#125;</span><br><span class="line"> </span><br><span class="line">    static_html = <span class="string">'/path/to/static.html'</span></span><br><span class="line"> </span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(static_html):</span><br><span class="line">        content = render_to_string(<span class="string">'template.html'</span>, context)</span><br><span class="line">        <span class="keyword">with</span> open(static_html, <span class="string">'w'</span>) <span class="keyword">as</span> static_file:</span><br><span class="line">            static_file.write(content)</span><br><span class="line"> </span><br><span class="line">    <span class="keyword">return</span> render(request, static_html)</span><br></pre></td></tr></table></figure><p>用Django管理静态网站内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">如果服务器上不支持Django环境，你可以在本地上搭建一个Django环境，然后生成静态页面，把这些页面放到不支持 Django 的服务器上去，在本地更新，然后上传到服务器，用Django来管理和更新网站的内容，也是一个不错的做法，还可以更安全，听说有很多黑客都是这么做的</span><br></pre></td></tr></table></figure><h4 id="十九-django的session"><a class="markdownIt-Anchor" href="#十九-django的session"></a> 十九、Django的session</h4><p>1、启用session</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">编辑settings.py中的一些配置:</span><br><span class="line">MIDDLEWARE_CLASSES 确保其中包含以下内容</span><br><span class="line">&apos;django.contrib.sessions.middleware.SessionMiddleware&apos;,</span><br><span class="line">INSTALLED_APPS 是包含:</span><br><span class="line">&apos;django.contrib.sessions&apos;,</span><br></pre></td></tr></table></figure><p>2、在视图中启用session:<strong>request.session</strong> 可以在视图中任何地方使用，它类似于python中的字典,session 默认有效时间为两周，可以在 <a href="http://settings.py" target="_blank" rel="noopener">settings.py</a> 中<code>SESSION_COOKIE_AGE</code>修改默认值。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建或修改 session：</span></span><br><span class="line">request.session[key] = value</span><br><span class="line"><span class="comment"># 获取 session：</span></span><br><span class="line">request.session.get(key,default=<span class="literal">None</span>)</span><br><span class="line"><span class="comment"># 删除 session</span></span><br><span class="line"><span class="keyword">del</span> request.session[key] <span class="comment"># 不存在时报错</span></span><br></pre></td></tr></table></figure><p>3、使用session的两个例子：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#一个不让用户评论两次的应用：</span></span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">post_comment</span><span class="params">(request, new_comment)</span>:</span></span><br><span class="line">    <span class="keyword">if</span> request.session.get(<span class="string">'has_commented'</span>, <span class="literal">False</span>):</span><br><span class="line">        <span class="keyword">return</span> HttpResponse(<span class="string">"You've already commented."</span>)</span><br><span class="line">    c = comments.Comment(comment=new_comment)</span><br><span class="line">    c.save()</span><br><span class="line">    request.session[<span class="string">'has_commented'</span>] = <span class="literal">True</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">'Thanks for your comment!'</span>)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#一个简化的登陆认证：</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">(request)</span>:</span></span><br><span class="line">    m = Member.objects.get(username=request.POST[<span class="string">'username'</span>])</span><br><span class="line">    <span class="keyword">if</span> m.password == request.POST[<span class="string">'password'</span>]:</span><br><span class="line">        request.session[<span class="string">'member_id'</span>] = m.id</span><br><span class="line">        <span class="keyword">return</span> HttpResponse(<span class="string">"You're logged in."</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> HttpResponse(<span class="string">"Your username and password didn't match."</span>)</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logout</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">del</span> request.session[<span class="string">'member_id'</span>]</span><br><span class="line">    <span class="keyword">except</span> KeyError:</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">"You're logged out."</span>)</span><br></pre></td></tr></table></figure><h4 id="二十-django传递数据给js"><a class="markdownIt-Anchor" href="#二十-django传递数据给js"></a> 二十、Django传递数据给js</h4><p>1、直接在视图函数（views.py中的函数）中渲染一个 list 或 dict 的内容，和网页其它部分一起显示到网页上（一次性地渲染，还是同一次请求）</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line">需要注意两点：</span><br><span class="line">1. views.py中返回的函数中的值要用 json.dumps()处理</span><br><span class="line">2. 在网页上要加一个 safe 过滤器。</span><br><span class="line">在views.py中：</span><br><span class="line"># -*- coding: utf-8 -*-</span><br><span class="line">from __future__ import unicode_literals</span><br><span class="line">import json</span><br><span class="line">from django.shortcuts import render</span><br><span class="line"> </span><br><span class="line">def home(request):</span><br><span class="line">    List = ['自强学堂', '渲染Json到模板']</span><br><span class="line">    Dict = &#123;'site': '自强学堂', 'author': '涂伟忠'&#125;</span><br><span class="line">    return render(request, 'home.html', &#123;</span><br><span class="line">            'List': json.dumps(List),</span><br><span class="line">            'Dict': json.dumps(Dict)</span><br><span class="line">        &#125;)</span><br><span class="line">在html中：</span><br><span class="line"><span class="meta">&lt;!DOCTYPE html&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">title</span>&gt;</span>欢迎光临 自强学堂！<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"list"</span>&gt;</span> 学习 <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">'dict'</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="actionscript">    <span class="comment">//列表</span></span></span><br><span class="line"><span class="actionscript">    <span class="keyword">var</span> List = &#123;&#123; List|safe &#125;&#125;;</span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="actionscript">    <span class="comment">//下面的代码把List的每一部分放到头部和尾部</span></span></span><br><span class="line"><span class="javascript">    $(<span class="string">'#list'</span>).prepend(List[<span class="number">0</span>]);</span></span><br><span class="line"><span class="javascript">    $(<span class="string">'#list'</span>).append(List[<span class="number">1</span>]);</span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="string">'--- 遍历 List 方法 1 ---'</span>)</span></span><br><span class="line"><span class="actionscript">    <span class="keyword">for</span>(i <span class="keyword">in</span> List)&#123;</span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(i);<span class="comment">// i为索引</span></span></span><br><span class="line"><span class="undefined">    &#125;</span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="string">'--- 遍历 List 方法 2 ---'</span>)</span></span><br><span class="line"><span class="actionscript">    <span class="keyword">for</span> (<span class="keyword">var</span> i = List.length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span></span><br><span class="line"><span class="actionscript">        <span class="comment">// 鼠标右键，审核元素，选择 console 可以看到输入的值。</span></span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(List[i]);</span></span><br><span class="line"><span class="undefined">    &#125;;</span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="string">'--- 同时遍历索引和内容，使用 jQuery.each() 方法 ---'</span>)</span></span><br><span class="line"><span class="javascript">    $.each(List, <span class="function"><span class="keyword">function</span>(<span class="params">index, item</span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(index);</span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(item);</span></span><br><span class="line"><span class="undefined">    &#125;);</span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="undefined"> </span></span><br><span class="line"><span class="actionscript">    <span class="comment">// 字典</span></span></span><br><span class="line"><span class="actionscript">    <span class="keyword">var</span> Dict = &#123;&#123; Dict|safe &#125;&#125;;</span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="string">"--- 两种字典的取值方式  ---"</span>)</span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(Dict[<span class="string">'site'</span>]);</span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(Dict.author);</span></span><br><span class="line"><span class="undefined">     </span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="string">"---  遍历字典  ---"</span>);</span></span><br><span class="line"><span class="actionscript">    <span class="keyword">for</span>(i <span class="keyword">in</span> Dict) &#123;</span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(i + Dict[i]);<span class="comment">//注意，此处 i 为键值</span></span></span><br><span class="line"><span class="undefined">    &#125;</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></div><div class="article-footer"><blockquote class="mt-2x"><ul class="post-copyright list-unstyled"><li class="post-copyright-link hidden-xs"><strong>本文链接：</strong> <a href="http://lizx999.gitee.io/xingges_blog/2019/04/16/Django笔记/" title="Django" target="_blank" rel="external">http://lizx999.gitee.io/xingges_blog/2019/04/16/Django笔记/</a></li><li class="post-copyright-license"><strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！</li></ul></blockquote><div class="panel panel-default panel-badger"><div class="panel-body"><figure class="media"><div class="media-left"><a href="https://gitee.com/lizx999" target="_blank" class="img-burn thumb-sm visible-lg"><img src="/xingges_blog/images/saodizeng.jpg" class="img-rounded w-full" alt></a></div><div class="media-body"><h3 class="media-heading"><a href="https://gitee.com/lizx999" target="_blank"><span class="text-dark">扫地僧</span><small class="ml-1x">一个半路出家的IT民工</small></a></h3><div>弃武从文，奋斗不止。</div></div></figure></div></div></div></article></div></main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter"><ul class="social-links"><li><a href="https://gitee.com/lizx999" target="_blank" title="Gitee" data-toggle="tooltip" data-placement="top"><i class="icon icon-gitee"></i></a></li><li><a href="/xingges_blog/atom.xml" target="_blank" title="Rss" data-toggle="tooltip" data-placement="top"><i class="icon icon-rss"></i></a></li></ul><div class="copyright">&copy; 2019 扫地僧<div class="publishby">Theme by <a href="https://github.com/cofess" target="_blank">cofess </a>base on <a href="https://github.com/cofess/hexo-theme-pure" target="_blank">pure</a>.</div></div></footer><script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script><script>window.jQuery||document.write('<script src="js/jquery.min.js"><\/script>')</script><script src="/xingges_blog/js/plugin.min.js"></script><script src="/xingges_blog/js/application.js"></script><script>!function(T){var n={TRANSLATION:{POSTS:"文章",PAGES:"页面",CATEGORIES:"分类",TAGS:"标签",UNTITLED:"(未命名)"},ROOT_URL:"/xingges_blog/",CONTENT_URL:"/xingges_blog/content.json"};T.INSIGHT_CONFIG=n}(window)</script><script src="/xingges_blog/js/insight.js"></script><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></body></html><!-- rebuild by neat -->